<?php

use app\modules\Admin\models\twostagelevelModel;
use Illuminate\Database\Capsule\Manager as DB;
use \app\service\member as memberService;

#[会员管理]
class MemberController extends AcommonController
{

    public function init()
    {
        $this->model      = (new memberModel)->withTrashed();
        $this->table      = 'member';
        $this->primaryKey = 'id';
        parent::init();
    }

    #[会员列表]
    public function indexAction($returnData = FALSE)
    {
        if ($this->isPost()) {
            $type     = $this->get('keywordsType');
            $keywords = $this->get('keywords');
            if ($keywords) {
                array_push($this->search, [$type, '=', $keywords]);
            }
            $startOn = $this->get('start_on');
            if (!empty($startOn)) {
                array_push($this->condition, ['created_at', '>=', $startOn]);
            }
            $endOn = $this->get('end_on');
            if (!empty($endOn)) {
                array_push($this->condition, ['created_at', '<=', $endOn]);
            }
            $status = $this->get('status');
            if (!empty($status)) {
                if($status=='deleted'){
                    $this->model = $this->model->whereNotNull('deleted_at');
                }else{
                    $this->model = $this->model->whereNull('deleted_at');
                    array_push($this->condition, ['status', '=', $status]);
                }
            }

            $returnData = parent::indexAction(true);
            foreach ($returnData['rows'] as $k => &$v) {
                $v['oauth'] = DB::table('member_oauth')->where('member_id', $v['id'])->select('id', 'provider','platform','unionid','openid','nickname','sex','headimgurl')->get();
            }
            json($returnData);
        } else {
            $this->_view->assign('enable_restore', $this->auth->roles_id==1);
            parent::indexAction();
        }
    }

    #[商城会员]
    public function memberAction()
    {
        if ($this->isPost()) {
            $type     = $this->get('keywordsType');
            $keywords = $this->get('keywords');
            if ($keywords) {
                array_push($this->search, [$type, '=', $keywords]);
            }
            $startOn = $this->get('start_on');
            if (!empty($startOn)) {
                array_push($this->condition, ['created_at', '>=', $startOn]);
            }
            $endOn = $this->get('end_on');
            if (!empty($endOn)) {
                array_push($this->condition, ['created_at', '<=', $endOn]);
            }
            $status = $this->get('status');
            if (!empty($status)) {
                if($status=='deleted'){
                    $this->model = $this->model->whereNotNull('deleted_at');
                }else{
                    $this->model = $this->model->whereNull('deleted_at');
                    array_push($this->condition, ['status', '=', $status]);
                }
            }
            $returnData = parent::indexAction(true);
            json($returnData);
        } else {
            $this->_view->assign('enable_restore', $this->auth->roles_id==1);
            $this->_view->display( strtolower($this->controller) . '/member.html');
        }
    }

    #[设置为股东]
    public function setGudongAction()
    {
        do {
            $rows = $this->postData;
            if (!$rows['gudong_id']) {
                $result = [
                    'ret' => 30001,
                    'msg' => '会员ID为空',
                ];
                break;
            }
            $remark             = $rows['remark'] ?: '管理员设置股东会员';
            $rows['created_at'] = date('Y-m-d H:i:s');
            $this->cleanTableColumn('gudong', $rows);
            DB::transaction(function () use ($rows, $remark) {
                gudongModel::insert($rows);
                $logRow = [
                    'gudong_id'  => $rows['gudong_id'],
                    'event'      => 'signin',
                    'event_id'   => 0,
                    'remark'     => $remark,
                    'oper_type'  => 'admin',
                    'oper_id'    => $this->auth->user_id,
                    'created_at' => date('Y-m-d H:i:s'),
                ];
                DB::table('gudong_log')->insert($logRow);
            });
            $result = [
                'ret'  => 0,
                'msg'  => '操作成功',
                'data' => $rows
            ];
        } while (FALSE);
        json($result);
    }

    #[会员添加]
    public function addAction()
    {
        if ($this->isPost()) {
            do {
                $rows  = $this->postData;
                $roles = [
                    'phone'       => ['role' => "required", 'msg' => '手机号'],
                    'nickname'    => ['role' => "required", 'msg' => '昵称'],
                    'resetPwd'    => ['role' => "required|min:6", 'msg' => '登陆密码'],
                    'resetPayPwd' => ['role' => "required|min:6", 'msg' => '支付密码'],
                ];
                Validate::check($rows, $roles);
                if (memberModel::where('phone', $rows['phone'])->exists()) {
                    ret(30002, '手机号已存在');
                }
                $rows['created_at'] = date('Y-m-d H:i:s');
                unset($rows[$this->primaryKey], $rows['updated_at'], $rows['deleted_at'], $rows['logined_at'], $rows['join_time']);
                if ($rows['resetPwd']) {
                    $rows['salt']     = substr(md5(uniqid(true)), 0, 6);
                    $rows['password'] = md5($rows['resetPwd'] . $rows['salt']);
                }
                if ($rows['resetPayPwd']) {
                    $rows['pay_password'] = md5($rows['resetPayPwd']);
                }
                $this->cleanColumn($rows);
                $query = $this->model;
                if ($insert_id = $query->insertGetId($rows)) {
                    // 记录团队关系邀请人邀请人
                    if ($rows['parent_member_id']>0) {
                        $to_insert = [['member_id' => $rows['parent_member_id'], 'level' => 1, 'children_id' => $insert_id]];
                        \memberchildrenModel::where('children_id', $rows['parent_member_id'])
                            ->select(['member_id', 'level'])
                            ->orderBy('level')
                            ->chunk(500, function($items) use ($insert_id, &$to_insert) {
                                foreach ($items as $item) {
                                    $to_insert[] = [
                                        'member_id' => $item->member_id,
                                        'level' => $item['level'] + 1,
                                        'children_id' => $insert_id,
                                    ];
                                }
                                \memberchildrenModel::insertOrIgnore($to_insert);
                                $to_insert = [];
                            });
                        if (!empty($to_insert)) {
                            \memberchildrenModel::insertOrIgnore($to_insert);
                        }
                    }
                    $result = [
                        'ret'  => 0,
                        'msg'  => '操作成功',
                        'data' => $insert_id,
                    ];
                } else {
                    $result = [
                        'ret' => 3,
                        'msg' => '数据插入失败',
                    ];
                }
            } while (FALSE);
            json($result);
        } else {
            parent::addAction();
        }
    }

    #[会员修改]
    public function editAction()
    {
        if (!$this->isPost()) {
            $this->model = $this->model->with(['gudong', 'tuike', 'qudai','twostage']);
            if (is_object($this->model)) {
                $query = $this->model;
            } else {
                $query = is_string($this->model) ? (new $this->model) : DB::table($this->table);
            }
            $id = $this->get($this->primaryKey, 0);
            if ($query->where($this->primaryKey, '=', $id)->doesntExist()) {
                throw new Exception("记录不存在");
            }
            $dataset                   = $query->where($this->primaryKey, '=', $id)->first();
            $dataset->parent           = $dataset->parent_member_id > 0 ? DB::table('member')->find($dataset->parent_member_id) : [];
            $dataset->child_user_count = DB::table('member_children')->where('member_id', $dataset->id)->where('children_deleted', 0)->count();
            $this->_view->assign('dataset', $dataset->toJson());
            $this->_view->display(strtolower($this->controller) . '/edit.html');
        } else {
            $query = $this->model;
            do {
                $rows  = $this->postData;
                $roles = [
                    $this->primaryKey => ['role' => "required|exists:{$this->table}.{$this->primaryKey}", 'msg' => '会员'],
                    'nickname'        => ['role' => "required", 'msg' => '昵称'],
                    'resetPwd'        => ['role' => "minlen:6", 'msg' => '登陆密码'],
                    'resetPayPwd'     => ['role' => "minlen:6", 'msg' => '支付密码'],
                ];
                if(memberModel::where('phone', '<>', '')->where('phone', $rows['phone'])->where('id', '<>', $rows['id'])->exists()){
                    $result = ['ret'=>30002, 'msg'=>'手机号重复'];
                    break;
                }
                Validate::check($rows, $roles);
                $rows['updated_at'] = date('Y-m-d H:i:s');
                unset($rows['created_at'], $rows['deleted_at'], $rows['logined_at'], $rows['join_time']);
                if ($rows['resetPwd']) {
                    $rows['salt']     = substr(md5(uniqid(true)), 0, 6);
                    $rows['password'] = md5($rows['resetPwd'] . $rows['salt']);
                }
                if ($rows['resetPayPwd']) {
                    $rows['pay_password'] = md5($rows['resetPayPwd']);
                }
                $this->cleanColumn($rows);
                if ($query->where($this->primaryKey, $rows[$this->primaryKey])->update($rows) !== FALSE) {
                    $result = [
                        'ret' => 0,
                        'msg' => '操作成功',
                    ];
                } else {
                    $result = [
                        'ret' => 3,
                        'msg' => '更新失败',
                    ];
                }
            } while (FALSE);
            json($result);
        }
    }

    #[佣金明细会员详情]
    public function rewardeditAction()
    {
        if (!$this->isPost()) {
            $this->model = $this->model->with(['gudong', 'tuike', 'qudai','twostage']);
            if (is_object($this->model)) {
                $query = $this->model;
            } else {
                $query = is_string($this->model) ? (new $this->model) : DB::table($this->table);
            }
            $id = $this->get($this->primaryKey, 0);
            if ($query->where($this->primaryKey, '=', $id)->doesntExist()) {
                throw new Exception("记录不存在");
            }
            $dataset                   = $query->where($this->primaryKey, '=', $id)->first();
            $dataset->parent           = $dataset->parent_member_id > 0 ? DB::table('member')->find($dataset->parent_member_id) : [];
            $dataset->child_user_count = DB::table('member_children')->where('member_id', $dataset->id)->where('children_deleted', 0)->count();
            $this->_view->assign('dataset', $dataset->toJson());
            $this->_view->display(strtolower($this->controller) . '/rewardedit.html');
        } else {
            $query = $this->model;
            do {
                $rows  = $this->postData;
                $roles = [
                    $this->primaryKey => ['role' => "required|exists:{$this->table}.{$this->primaryKey}", 'msg' => '会员'],
                    'nickname'        => ['role' => "required", 'msg' => '昵称'],
                    'resetPwd'        => ['role' => "minlen:6", 'msg' => '登陆密码'],
                    'resetPayPwd'     => ['role' => "minlen:6", 'msg' => '支付密码'],
                ];
                if(memberModel::where('phone', '<>', '')->where('phone', $rows['phone'])->where('id', '<>', $rows['id'])->exists()){
                    $result = ['ret'=>30002, 'msg'=>'手机号重复'];
                    break;
                }
                Validate::check($rows, $roles);
                $rows['updated_at'] = date('Y-m-d H:i:s');
                unset($rows['created_at'], $rows['deleted_at'], $rows['logined_at'], $rows['join_time']);
                if ($rows['resetPwd']) {
                    $rows['salt']     = substr(md5(uniqid(true)), 0, 6);
                    $rows['password'] = md5($rows['resetPwd'] . $rows['salt']);
                }
                if ($rows['resetPayPwd']) {
                    $rows['pay_password'] = md5($rows['resetPayPwd']);
                }
                $this->cleanColumn($rows);
                if ($query->where($this->primaryKey, $rows[$this->primaryKey])->update($rows) !== FALSE) {
                    $result = [
                        'ret' => 0,
                        'msg' => '操作成功',
                    ];
                } else {
                    $result = [
                        'ret' => 3,
                        'msg' => '更新失败',
                    ];
                }
            } while (FALSE);
            json($result);
        }
    }

    #[会员删除]
    public function deleteAction()
    {
        do {
            $id = $this->get($this->primaryKey, []);
            if (empty($id)) {
                $result = [
                    'ret' => 2,
                    'msg' => '参数为空',
                ];
                break;
            }
            if(is_object($this->model)){
                $query = $this->model;
            }else{
                $query = is_string($this->model) ? (new $this->model) : DB::table($this->table);
            }
            if (is_array($id)) {
                if ($query->whereIn($this->primaryKey, $id)->delete()) {
                    $result = [
                        'ret' => 0,
                        'msg' => '操作成功',
                    ];
                    break;
                }
            } elseif (is_numeric($id)) {
                if ($query->where($this->primaryKey, '=', $id)->doesntExist()) {
                    $result = [
                        'ret' => 4,
                        'msg' => '记录不存在',
                    ];
                    break;
                }
                if ($query->where($this->primaryKey, '=', $id)->delete()) {
                    memberchildrenModel::where('children_id', $id)->update(['children_deleted'=>1]);
                    $result = [
                        'ret' => 0,
                        'msg' => '操作成功',
                    ];
                    break;
                }
            }
            $result = [
                'ret' => '5',
                'msg' => '删除失败',

            ];
        } while (FALSE);
        json($result);
    }

    #[合并账号]
    public function mergeAction()
    {
        if ($this->isPost()) {
            do {
                $inputs = $this->postData;
                $rules  = [
                    'source_id' => ['role' => 'required|exists:member.id', 'msg' => '源账号'],
                    'target_id' => ['role' => 'required|exists:member.id', 'msg' => '目标账号'],
                ];
                Validate::check($inputs, $rules);
                if(\memberModel::where('id', $inputs['source_id'])->doesntExist()){
                    ret('30001', '源账号不存在或已被删除');
                }
                if(\memberModel::where('id', $inputs['target_id'])->doesntExist()){
                    ret('30002', '目标账号不存在或已被删除');
                }
                memberService::merge($inputs['source_id'], $inputs['target_id'], 'admin', $this->auth->user_id, '后台管理员操作账号合并');
                $result = [
                    'ret' => 0,
                    'msg' => '操作成功',
                ];
            } while (FALSE);
            json($result);
        } else {
            $this->_view->display(strtolower($this->controller) . '/merge.html');
        }
    }

    #[合并账号记录]
    public function mergelogAction()
    {
        if ($this->isPost()) {
            $params   = $this->postData;
            $page     = $params['page'] ?? 1;
            $per_page = $params['rows'] ?? 10;

            $rewardModel = (new membermergeModel)->newQuery();
            $query       = $rewardModel->with(['target'])->orderByDesc('created_at');
            if (isset($params['start_on']) && !empty($params['start_on'])) {
                $query = $query->whereDate('created_at', '>=', $params['start_on']);
            }
            if (isset($params['end_on']) && !empty($params['end_on'])) {
                $query = $query->whereDate('created_at', '<=', $params['end_on']);
            }
            if (isset($params['keywords']) && !empty($params['keywords'])) {
                if (isset($params['keywordsType']) && !empty($params['keywordsType'])) {
                    switch ($params['keywordsType']) {
                        case 'source_id':
                            $query = $query->where('source_id', $params['keywords']);
                            break;
                        case 'member_id':
                            $query = $query->where('target_id', $params['keywords']);
                            break;
                        case 'phone':
                            $member_id = memberModel::query()->where('phone', $params['keywords'])->value('id');
                            $query     = $query->where('target_id', $member_id);
                            break;
                        case 'nickname':
                            $member_ids = memberModel::query()->where('nickname', 'like', "%{$params['keywords']}%")->pluck('id');
                            $query      = $query->whereIn('target_id', $member_ids);
                            break;
                    }
                }
            }
            $total = $query->count();
            if (isset($params['sort'])) {
                $query = $query->orderBy($params['sort'] ?: 'id', (isset($params['order']) && in_array($params['order'], ['asc', 'desc'])) ? $params['order'] : 'desc');
            }
            $data = $query->offset(($page - 1) * $per_page)
                ->limit($per_page)
                ->get()->toArray();
            json([
                'total' => $total,
                'rows'  => $data
            ]);
        } else {
            $this->_view->display(strtolower($this->controller) . '/mergelog.html');
        }
    }

    #[等级修改]
    public function levelAction()
    {
        $id    = $this->get('id');
        $level = $this->get('level');
        if ($this->isPost()) {
            memberService::level($id, $level, 'admin', $this->auth->user_id);
            json(['ret' => 0,'msg' => '操作成功']);
        } else {
            $this->_view->assign('id', $id);
            $this->_view->assign('curr', $this->get('curr'));
            $this->_view->display(strtolower($this->controller) . '/level.html');
        }
    }

    #[推客等级]
    public function tuikelevelAction()
    {
        $id = $this->get('id');
        if ($this->isPost()) {
            $query = new tuikelevelModel();
            $total = $query->count();
            $sort  = $this->get('sort', 'level');
            $order = $this->get('order', 'asc');
            $query = $query->orderBy($sort, $order);
            $rows  = $query->get();
            if (!empty($this->appends)) {
                foreach ($this->appends as $append) {
                    $rows = $rows->append($append);
                }
            }
            json(['total' => $total, 'rows' => $rows]);
        } else {
            $this->_view->assign('id', $id);
            $this->_view->display(strtolower($this->controller) . '/tuikelevel.html');
        }
    }

    #[设置推客]
    public function setTuikeAction()
    {
        $id    = $this->get('id');
        $level = $this->get('level');
        try {
            DB::beginTransaction();
            $row = [
                'tuike_id'   => $id,
                'level'      => $level,
                'created_at' => date('Y-m-d H:i:s')
            ];
            tuikeModel::insert($row);
            $log = [
                'tuike_id'   => $id,
                'event'      => 'signin',
                'after'      => $level,
                'remark'     => '管理员设置用户为推客，等级为：' . $level,
                'oper_type'  => 'admin',
                'oper_id'    => $this->auth->user_id,
                'created_at' => date('Y-m-d H:i:s')
            ];
            tuikelogModel::insert($log);
            DB::commit();
            $result = [
                'ret'  => 0,
                'msg'  => '操作成功',
                'data' => $row
            ];
        } catch (Exception $e) {
            DB::rollback();
            $result = [
                'ret' => 30001,
                'msg' => $e->getMessage(),
            ];
        }
        json($result);
    }

    #[推广大使等级]
    public function twostagelevelAction()
    {
        $id = $this->get('id');
        if ($this->isPost()) {
            $query = new twostagelevelModel();
            $total = $query->count();
            $sort  = $this->get('sort', 'level');
            $order = $this->get('order', 'asc');
            $query = $query->orderBy($sort, $order);
            $rows  = $query->get();
            if (!empty($this->appends)) {
                foreach ($this->appends as $append) {
                    $rows = $rows->append($append);
                }
            }
            json(['total' => $total, 'rows' => $rows]);
        } else {
            $this->_view->assign('id', $id);
            $this->_view->display(strtolower($this->controller) . '/twostagelevel.html');
        }
    }

    #[设置推广大使]
    public function settwostageAction()
    {
        $id    = $this->get('id');
        $level = $this->get('level');
        try {
            DB::beginTransaction();
            $row = [
                'twostage_id'   => $id,
                'level'      => $level,
                'created_at' => date('Y-m-d H:i:s')
            ];
            \app\modules\Admin\models\twostageModel::insert($row);
            $log = [
                'twostage_id'   => $id,
                'event'      => 'signin',
                'after'      => $level,
                'remark'     => '管理员设置用户为推广大使，等级为：' . $level,
                'oper_type'  => 'admin',
                'oper_id'    => $this->auth->user_id,
                'created_at' => date('Y-m-d H:i:s')
            ];
            \app\modules\Admin\models\twostagelogModel::insert($log);
            DB::commit();
            $result = [
                'ret'  => 0,
                'msg'  => '操作成功',
                'data' => $row
            ];
        } catch (Exception $e) {
            DB::rollback();
            $result = [
                'ret' => 30001,
                'msg' => $e->getMessage(),
            ];
        }
        json($result);
    }

    #[区代等级]
    public function qudailevelAction()
    {
        $id = $this->get('id');
        if ($this->isPost()) {

            $keywords = $this->get('keywords');
            $query    = DB::table('area');
            if ($keywords !== '') {
                $query = $query->where('name', 'like', "%{$keywords}%");
            } else {
                $query = $query->where('pid', '=', '0');
            }
            $rows = $query->select('id', 'pid', 'level', 'name as text')->get();
            if ($keywords !== '') {
                $dataset = [];
                foreach ($rows as $k => $v) {
                    if ($v->level == 3) {
                        $upper = DB::table('area')->where('id', $v->pid)->first();
                        $toper = DB::table('area')->where('id', $upper->pid)->first();
                        $arr   = [
                            'id'       => $toper->id,
                            'text'     => $toper->name,
                            'level'    => $toper->level,
                            'children' => [
                                [
                                    'id'       => $upper->id,
                                    'text'     => $upper->name,
                                    'level'    => $upper->level,
                                    'children' => [
                                        [
                                            'id'    => $v->id,
                                            'text'  => $v->text,
                                            'level' => $v->level,
                                        ]
                                    ]
                                ]
                            ]
                        ];
                        array_push($dataset, $arr);
                    } elseif ($v->level == 2) {
                        $upper = DB::table('area')->where('id', $v->pid)->first();
                        $arr   = [
                            'id'       => $upper->id,
                            'text'     => $upper->name,
                            'level'    => $upper->level,
                            'children' => [$v]
                        ];
                        array_push($dataset, $arr);
                    } else {
                        array_push($dataset, $v);
                    }
                }
                if ($dataset) {
                    ret(0, 'areas', $dataset);
                } else {
                    ret(10000, '未找到匹配区域');
                }
            } else {
                $allCity = DB::table('area')->where('level', 2)->select('id', 'pid', 'name as text', 'level')->get();
                $allArea = DB::table('area')->where('level', 3)->select('id', 'pid', 'name as text', 'level')->get();
                foreach ($rows as $k1 => &$v1) {
                    $v1->children = [];
                    foreach ($allCity as $k2 => &$v2) {
                        if ($v2->pid == $v1->id) {
                            $v2->children = [];
                            foreach ($allArea as $k3 => &$v3) {
                                if ($v3->pid == $v2->id) {
                                    array_push($v2->children, $v3);
                                }
                            }
                            array_push($v1->children, $v2);
                        }
                    }
                }
            }
            ret(0, 'areas', $rows);

        } else {
            $query = DB::table('area');
            $query = $query->where('pid', '=', '0');

            $rows    = $query->select('id', 'name as text', 'level')->get();
            $allCity = DB::table('area')->where('level', 2)->select('id', 'pid', 'name as text', 'level')->get();
            $allArea = DB::table('area')->where('level', 3)->select('id', 'pid', 'name as text', 'level')->get();
            foreach ($rows as $k1 => &$v1) {
                $v1->children = [];
                foreach ($allCity as $k2 => &$v2) {
                    if ($v2->pid == $v1->id) {
                        $v2->children = [];
                        foreach ($allArea as $k3 => &$v3) {
                            if ($v3->pid == $v2->id) {
                                array_push($v2->children, $v3);
                            }
                        }
                        array_push($v1->children, $v2);
                    }
                }
            }
            $this->_view->assign('areas', $rows);
            $this->_view->assign('id', $id);
            $this->_view->display(strtolower($this->controller) . '/qudailevel.html');
        }
    }

    #[设置区代]
    public function setQudaiAction()
    {
        $id   = $this->get('id');
        $area = $this->get('area');
        if($area['level']<2){
            ret(30001, '请选择到市/区');
        }
        $company_name = $this->get('company_name');
        if(empty($company_name)){
            ret(30001, '请输入企业名称');
        }
        $company_representative_name = $this->get('company_representative_name');
        if(empty($company_representative_name)){
            ret(30001, '请输入企业法人');
        }
        $phone = $this->get('phone');
        if(empty($phone)){
            ret(30001, '请输入企业联系电话');
        }

        try {
            $area_parent = areaModel::query()->findOrFail($area['pid']);
            $area['text'] = $area_parent->name.$area['text'];
            if(intval($area['level']) === 3){
                $area_parent_p = areaModel::query()->findOrFail($area_parent->pid);
                $area['text'] = $area_parent_p->name.$area['text'];
            }
            unset($area_parent, $area_parent_p);
            if(qudaiModel::query()->where('area_level', $area['level'])->where('area', $area['id'])->exists()){
                throw new Exception("{$area['text']}当前区域已经存在代理！");
            }
            if(qudaiModel::query()->where('company_name', $company_name)->exists()){
                throw new Exception("企业名称已经存在！");
            }
            DB::beginTransaction();
            $row = [
                'qudai_id'   => $id,
                'area'       => $area['id'],
                'area_name'  => $area['text'],
                'area_level' => $area['level'],
                'company_name'  => $company_name,
                'company_representative_name' => $company_representative_name,
                'phone' => $phone,
                'created_at' => timestamp(),
                'updated_at' => timestamp(),
            ];
            qudaiModel::insert($row);
            $log = [
                'qudai_id'   => $id,
                'event'      => 'signin',
                'remark'     => '管理员设置用户为区域代理商，所在区域为：' . $area['text'],
                'oper_type'  => 'admin',
                'oper_id'    => $this->auth->user_id,
                'created_at' => date('Y-m-d H:i:s')
            ];
            qudailogModel::insert($log);
            DB::commit();
            $result = [
                'ret'  => 0,
                'msg'  => '操作成功',
                'data' => $row
            ];
        } catch (Exception $e) {
            DB::rollback();
            $result = [
                'ret' => 30001,
                'msg' => $e->getMessage(),
            ];
        }
        json($result);
    }

    #[账户充值]
    public function rechargeAction()
    {
        $rechargeMode = [
            'money' => '余额',
            'score' => '积分',
            'hongbao' => '兑换券',
            'jindou' => '股权',
        ];
        if ($this->isPost()) {
            $rows  = $this->postData;
            $roles = [
                'member_id' => ['role' => "required|exists:member.id", 'msg' => '会员'],
                'money'     => ['role' => "required|neq:0", 'msg' => '金额'],
            ];
            Validate::check($rows, $roles);
            try {
                DB::beginTransaction();
                $show_num = ($rows['mode'] == 'money')?'金额':'数量';
                $remark = "用户{$rechargeMode[$rows['mode']]}充值, {$show_num}为：{$rows['money']}";
                if(!empty($rows['remark'])){
                    $remark = $rows['remark'];
                }
                $new_remark = $remark.PHP_EOL.'操作管理员：'.$this->auth->username.'(ID:'.$this->auth->user_id.')';
                switch ($rows['mode']){
                    case 'money':
                        $before = memberModel::where('id', $rows['member_id'])->value('money');
                        memberModel::where('id', $rows['member_id'])->increment('money', $rows['money']);
                        $log = [
                            'member_id'  => $rows['member_id'],
                            'event'      => 'backofficechange',
                            'event_id'   => 0,
                            'money'      => $rows['money'],
                            'before'     => $before,
                            'after'      => $before + $rows['money'],
                            'remark'     => $new_remark,
                            'oper_type'  => 'admin',
                            'oper_id'    => $this->auth->user_id,
                            'created_at' => date('Y-m-d H:i:s')
                        ];
                        membermoneylogModel::insert($log);
                        break;
                    case 'score':
                        $before = memberModel::where('id', $rows['member_id'])->value('score');
                        memberModel::where('id', $rows['member_id'])->increment('score', $rows['money']);
                        $log = [
                            'member_id'  => $rows['member_id'],
                            'event'      => 'backofficechange',
                            'event_id'   => 0,
                            'score'      => $rows['money'],
                            'before'     => $before,
                            'after'      => $before + $rows['money'],
                            'remark'     => $new_remark,
                            'oper_type'  => 'admin',
                            'oper_id'    => $this->auth->user_id,
                            'created_at' => date('Y-m-d H:i:s')
                        ];
                        memberscorelogModel::insert($log);
                        break;
                    case 'jindou':
                        $before = memberModel::where('id', $rows['member_id'])->value('jindou');
                        memberModel::where('id', $rows['member_id'])->increment('jindou', $rows['money']);
                        $log = [
                            'member_id'  => $rows['member_id'],
                            'event'      => 'backofficechange',
                            'event_id'   => 0,
                            'jindou'      => $rows['money'],
                            'before'     => $before,
                            'after'      => $before + $rows['money'],
                            'remark'     => $new_remark,
                            'oper_type'  => 'admin',
                            'oper_id'    => $this->auth->user_id,
                            'created_at' => date('Y-m-d H:i:s')
                        ];
                        \app\modules\Admin\models\memberjindoulogModel::insert($log);
                        break;
                    case 'hongbao':
                        $before = memberModel::where('id', $rows['member_id'])->value('hongbao');
                        memberModel::where('id', $rows['member_id'])->increment('hongbao', $rows['money']);
                        $log = [
                            'member_id'  => $rows['member_id'],
                            'event'      => 'backofficechange',
                            'event_id'   => 0,
                            'hongbao'      => $rows['money'],
                            'before'     => $before,
                            'after'      => $before + $rows['money'],
                            'remark'     => $new_remark,
                            'oper_type'  => 'admin',
                            'oper_id'    => $this->auth->user_id,
                            'created_at' => date('Y-m-d H:i:s')
                        ];
                        \app\modules\Admin\models\memberhongbaologModel::insert($log);
                        break;
                    default:
                }
                DB::commit();
                $result = [
                    'ret'  => 0,
                    'msg'  => '操作成功',
                    'data' => $log['after']
                ];
            } catch (Exception $e) {
                DB::rollback();
                $result = [
                    'ret' => 30001,
                    'msg' => $e->getMessage(),
                ];
            }
            json($result);
        } else {
            $id   = $this->get('id');
            $mode = $this->get('mode');
            $this->_view->assign('id', $id);
            $this->_view->assign('mode', $mode);
            $this->_view->assign('modeList', json_encode($rechargeMode, 256));
            switch ($mode){
                case 'score':
                    $this->_view->assign('curr_money', memberModel::where('id', $id)->value('score'));
                    break;
                case 'hongbao':
                    $this->_view->assign('curr_money', memberModel::where('id', $id)->value('hongbao'));
                    break;
                case 'jindou':
                    $this->_view->assign('curr_money', memberModel::where('id', $id)->value('jindou'));
                    break;
                default:
                    $this->_view->assign('curr_money', memberModel::where('id', $id)->value('money'));
            }
            $this->_view->assign('frompage', $this->get('frompage', 'member'));
            $this->_view->display(strtolower($this->controller) . '/recharge.html');
        }
    }

    #[团队信息]
    public function teamAction()
    {
        $id = $this->get('id');
        if ($this->isPost()) {
            $rows  = DB::table('member_children')
                ->where('member_id', $id)
                ->where('children_deleted', 0)
                ->groupBy('level')
                ->select('member_id', 'level', DB::raw('count(*) as counter'))
                ->get();
            $total = $rows->count();
            json(['total' => $total, 'rows' => $rows]);
        } else {
            $name = $this->get('name');
            $this->_view->assign('id', $id);
            $this->_view->assign('name', $name);
            $levelList       = agentlevelModel::get();
            $this->_view->assign('levelList', $levelList);
            $this->_view->display(strtolower($this->controller) . '/team.html');
        }
    }

    #[直推团队信息]
    public function teamv1Action()
    {
        $id = $this->get('id');
        if ($this->isPost()) {
            if (is_object($this->model)) {
                $query = $this->model;
            } else {
                $query = is_string($this->model) ? (new $this->model) : DB::table($this->table);
            }
            $query = $query->join('member_children', 'member.id', '=', 'member_children.children_id')
                ->where('member_children.member_id', $id)
                ->where('member_children.level', 1)
                ->where('member_children.children_deleted', 0)
                ->select('member.*');
            $total = $query->count();
            $sort  = $this->get('sort', 'sortorder');
            $order = $this->get('order', 'desc');
            $query = $query->orderBy($sort, $order)->orderBy($this->primaryKey, 'DESC');
            $page  = $this->get('page');
            if (!empty($page)) {
                $limit  = $this->get('rows', 10);
                $offset = ($page - 1) * $limit;
                $query  = $query->offset($offset)->limit($limit);
            }
            $rows = $query->get();
            foreach ($rows as $k => &$v) {
                $v->child_user_count = DB::table('member_children')->where('member_id', $v->id)->where('children_deleted', 0)->count();
            }
            json(['total' => $total, 'rows' => $rows]);
        } else {
            $name = $this->get('name');
            $this->_view->assign('id', $id);
            $this->_view->assign('name', $name);
            $this->_view->display(strtolower($this->controller) . '/teamv1.html');
        }
    }

    #[团队列表]
    public function teamlistAction()
    {
        $id    = $this->get('id');
        $level = $this->get('level', 0);
        $agent_level = $this->get('agent_level', 0);
        if ($this->isPost()) {
            if (is_object($this->model)) {
                $query = $this->model;
            } else {
                $query = is_string($this->model) ? (new $this->model) : DB::table($this->table);
            }
            $query = $query->join('member_children', 'member.id', '=', 'member_children.children_id')
                ->where('member_children.member_id', $id)
                ->whereNull('member.deleted_at');
            if($level>0){
                $query = $query->where('member_children.level', $level);
            }
            if($agent_level>0){
                $query = $query->where('member.level', $agent_level);
            }
            $type     = $this->get('keywordsType');
            $keywords = $this->get('keywords');
            if ($keywords) {
                $query = $query->where('member.'.$type, $keywords);
            }
            $query = $query->select('member.*');
            $total = $query->count();
            $sort  = $this->get('sort', 'sortorder');
            $order = $this->get('order', 'desc');
            $query = $query->orderBy($sort, $order)->orderBy($this->primaryKey, 'DESC');
            $page  = $this->get('page');
            if (!empty($page)) {
                $limit  = $this->get('rows', 10);
                $offset = ($page - 1) * $limit;
                $query  = $query->offset($offset)->limit($limit);
            }
            $rows = $query->get();
            foreach ($rows as $k => &$v) {
                $v->child_user_count = DB::table('member_children')->where('member_id', $v->id)->where('children_deleted', 0)->count();
            }
            json(['total' => $total, 'rows' => $rows]);
        } else {
            $this->_view->assign('id', $id);
            $this->_view->assign('level', $level);
            $this->_view->display(strtolower($this->controller) . '/teamlist.html');
        }
    }

    #[团队列表导出]
    public function exportteamlistAction()
    {
        $id   = $this->get('id');
        $level     = $this->get('level');
        $agent_level = $this->get('agent_level');
        $keywordsType = $this->get('keywordsType');
        $keywords = $this->get('keywords');

        $dirpath = APP_PATH . '/public/excel/';
        if ($dirpath !== '.' && !file_exists($dirpath)) {
            mkdir($dirpath, 0777, true);
        }
        $filename = 'AgentTeamList_'. $id .'_'. date('Ymd') . uniqid() . '.xlsx';
        $filepath = $dirpath . $filename;
        $res = exec("php ". APP_PATH . "/public/cli.php export/agentTeamList \"id={$id}&keywords={$keywords}&level={$level}&agent_level={$agent_level}&type={$keywordsType}&path={$filepath}\"");
        if ($res === 'Done' && file_exists($filepath)) {
            if( $webpath = syncFile($filepath) ){
                ret(0, '团队列表导出excel成功', $webpath);
            }
        }
        ret(30003, '团队列表导出失败');
    }

    #[消费金额]
    public function totalConsumeAction()
    {
        $id   = $this->get('id');
        $name = $this->get('name');
        if ($this->isPost()) {
            $params = [
                'id'           => $id,
                'start_on'     => $this->get('start_on'),
                'end_on'       => $this->get('end_on'),
                'keywordsType' => $this->get('keywordsType'),
                'keywords'     => $this->get('keywords'),
                'sort'         => $this->get('sort'),
                'order'        => $this->get('order'),
                'page'         => $this->get('page'),
                'rows'         => $this->get('rows'),
            ];
            $result = memberService::totalConsume($params);
            json($result);
        } else {
            $this->_view->assign('id', $id);
            $this->_view->assign('name', $name);
            $this->_view->display(strtolower($this->controller) . '/totalconsume.html');
        }
    }

    #[个人消费明细导出]
    public function exportTotalConsumeAction()
    {
        $id   = $this->get('id');
        $type     = $this->get('keywordsType');
        $keywords = $this->get('keywords');
        $startOn = $this->get('start_on');
        $endOn = $this->get('end_on');

        $dirpath = APP_PATH . '/public/excel/';
        if ($dirpath !== '.' && !file_exists($dirpath)) {
            mkdir($dirpath, 0777, true);
        }
        $filename = 'agentTotalConsume_'. $id .'_'. date('Ymd') . uniqid() . '.xlsx';
        $filepath = $dirpath . $filename;
        $res = exec("php ". APP_PATH . "/public/cli.php export/agentTotalConsume \"type={$type}&keywords={$keywords}&id={$id}&startOn={$startOn}&endOn={$endOn}&path={$filepath}\"");
        if ($res === 'Done' && file_exists($filepath)) {
            if( $webpath = syncFile($filepath) ){
                ret(0, '个人消费明细导出excel成功', $webpath);
            }
        }
        ret(30003, '个人消费明细导出失败');
    }

    #[团队业绩]
    public function teamConsumeAction()
    {
        $id   = $this->get('id');
        $name = $this->get('name');
        if ($this->isPost()) {
            $params = [
                'id'           => $id,
                'start_on'     => $this->get('start_on'),
                'end_on'       => $this->get('end_on'),
                'keywordsType' => $this->get('keywordsType'),
                'keywords'     => $this->get('keywords'),
                'sort'         => $this->get('sort'),
                'order'        => $this->get('order'),
                'page'         => $this->get('page'),
                'rows'         => $this->get('rows'),
            ];
            if( $this->get('mode')=='included' ) {
                $result = memberService::teamConsume($params);
            } else {
                $result = memberService::teamConsumeRefund($params);
            }
            json($result);
        } else {
            $this->_view->assign('id', $id);
            $this->_view->assign('name', $name);
            $this->_view->display(strtolower($this->controller) . '/teamconsume.html');
        }
    }

    #[财富区业绩]
    public function cfteamConsumeAction()
    {
        $id   = $this->get('id');
        $name = $this->get('name');
        if ($this->isPost()) {
            $params = [
                'id'           => $id,
                'start_on'     => $this->get('start_on'),
                'end_on'       => $this->get('end_on'),
                'keywordsType' => $this->get('keywordsType'),
                'keywords'     => $this->get('keywords'),
                'sort'         => $this->get('sort'),
                'order'        => $this->get('order'),
                'page'         => $this->get('page'),
                'rows'         => $this->get('rows'),
            ];
            if( $this->get('mode')=='included' ) {
                $result = memberService::cfteamConsume($params);
            } else {
                $result = memberService::cfteamConsumeRefund($params);
            }
            json($result);
        } else {
            $this->_view->assign('id', $id);
            $this->_view->assign('name', $name);
            $this->_view->display(strtolower($this->controller) . '/cfteamconsume.html');
        }
    }

    #[团队业绩明细导出]
    public function exportTeamConsumeAction()
    {
        $id   = $this->get('id');
        $type     = $this->get('keywordsType');
        $keywords = $this->get('keywords');
        $startOn = $this->get('start_on');
        $endOn = $this->get('end_on');
        $mode = $this->get('mode');

        $dirpath = APP_PATH . '/public/excel/';
        if ($dirpath !== '.' && !file_exists($dirpath)) {
            mkdir($dirpath, 0777, true);
        }
        $filename = 'agentTeamConsume_'. $id .'_'.($mode?:'included'). date('Ymd') . uniqid() . '.xlsx';
        $filepath = $dirpath . $filename;
        $res = exec("php ". APP_PATH . "/public/cli.php export/agentTeamConsume \"mode={$mode}&type={$type}&keywords={$keywords}&id={$id}&startOn={$startOn}&endOn={$endOn}&path={$filepath}\"");
        if ($res === 'Done' && file_exists($filepath)) {
            if( $webpath = syncFile($filepath) ){
                ret(0, '团队业绩明细导出excel成功', $webpath);
            }
        }
        ret(30003, '团队业绩明细导出失败');
    }


    #[直推业绩]
    public function teamConsumeV1Action()
    {
        $id   = $this->get('id');
        $name = $this->get('name');
        if ($this->isPost()) {
            $params = [
                'id'           => $id,
                'start_on'     => $this->get('start_on'),
                'end_on'       => $this->get('end_on'),
                'keywordsType' => $this->get('keywordsType'),
                'keywords'     => $this->get('keywords'),
                'sort'         => $this->get('sort'),
                'order'        => $this->get('order'),
                'page'         => $this->get('page'),
                'rows'         => $this->get('rows'),
            ];
            if( $this->get('mode')=='included' ) {
                $result = memberService::teamConsumeV1($params);
            } else {
                $result = memberService::teamConsumeV1Refund($params);
            }
            json($result);
        } else {
            $this->_view->assign('id', $id);
            $this->_view->assign('name', $name);
            $this->_view->display(strtolower($this->controller) . '/teamconsumev1.html');
        }
    }

    #[直推业绩明细导出]
    public function exportTeamConsumeV1Action()
    {
        $id   = $this->get('id');
        $type     = $this->get('keywordsType');
        $keywords = $this->get('keywords');
        $startOn = $this->get('start_on');
        $endOn = $this->get('end_on');
        $mode = $this->get('mode');

        $dirpath = APP_PATH . '/public/excel/';
        if ($dirpath !== '.' && !file_exists($dirpath)) {
            mkdir($dirpath, 0777, true);
        }
        $filename = 'agentTeamConsumeV1_'. $id .'_'.($mode?:'included'). date('Ymd') . uniqid() . '.xlsx';
        $filepath = $dirpath . $filename;
        $res = exec("php ". APP_PATH . "/public/cli.php export/agentTeamConsumeV1 \"mode={$mode}&type={$type}&keywords={$keywords}&id={$id}&startOn={$startOn}&endOn={$endOn}&path={$filepath}\"");
        if ($res === 'Done' && file_exists($filepath)) {
            if( $webpath = syncFile($filepath) ){
                ret(0, '团队业绩明细导出excel成功', $webpath);
            }
        }
        ret(30003, '团队业绩明细导出失败');
    }

    #[上级列表]
    public function upperAction()
    {
        $id = $this->get('id');
        if ($this->isPost()) {
            if (is_object($this->model)) {
                $query = $this->model;
            } else {
                $query = is_string($this->model) ? (new $this->model) : DB::table($this->table);
            }
            $query = $query->join('member_children', 'member.id', '=', 'member_children.member_id')
                ->where('member_children.children_id', $id)
                ->select('member.id', 'member.phone', 'member.level', 'member.nickname', 'member.avatar', 'member.parent_member_id', 'member.money', 'member.score',
                    'member.total_income', 'member.total_consume', 'member.team_consume', 'member.status', 'member.created_at', 'member_children.level as upper_level');
            $total = $query->count();
            $sort  = $this->get('sort', 'sortorder');
            $order = $this->get('order', 'desc');
            $query = $query->orderBy($sort, $order)->orderBy($this->primaryKey, 'DESC');
            $page  = $this->get('page');
            if (!empty($page)) {
                $limit  = $this->get('rows', 10);
                $offset = ($page - 1) * $limit;
                $query  = $query->offset($offset)->limit($limit);
            }
            $rows = $query->get();
            foreach ($rows as $k => &$v) {
                $v->child_user_count = DB::table('member_children')->where('member_id', $v->id)->where('children_deleted', 0)->count();
            }
            json(['total' => $total, 'rows' => $rows]);
        } else {
            $this->_view->assign('id', $id);
            $this->_view->display(strtolower($this->controller) . '/upper.html');
        }
    }

    #[会员关系变动记录]
    public function relationAction()
    {
        if ($this->isPost()) {
            $params   = $this->postData;
            $page     = $params['page'] ?? 1;
            $per_page = $params['rows'] ?? 10;

            $rewardModel = (new memberrelationModel())->newQuery();
            $query       = $rewardModel->with(['member'])->orderByDesc('created_at');
            if (isset($params['start_on']) && !empty($params['start_on'])) {
                $query = $query->whereDate('created_at', '>=', $params['start_on']);
            }
            if (isset($params['end_on']) && !empty($params['end_on'])) {
                $query = $query->whereDate('created_at', '<=', $params['end_on']);
            }
            if (isset($params['keywords']) && !empty($params['keywords'])) {
                if (isset($params['keywordsType']) && !empty($params['keywordsType'])) {
                    switch ($params['keywordsType']) {
                        case 'member_id':
                            $query = $query->where('member_id', $params['keywords']);
                            break;
                        case 'phone':
                            $member_id = memberModel::query()->where('phone', $params['keywords'])->value('id');
                            $query     = $query->where('member_id', $member_id);
                            break;
                        case 'nickname':
                            $member_ids = memberModel::query()->where('nickname', 'like', "%{$params['keywords']}%")->pluck('id');
                            $query      = $query->whereIn('member_id', $member_ids);
                            break;
                    }
                }
            }
            $total = $query->count();
            if (isset($params['sort'])) {
                $query = $query->orderBy($params['sort'] ?: 'id', (isset($params['order']) && in_array($params['order'], ['asc', 'desc'])) ? $params['order'] : 'desc');
            }
            $data = $query->offset(($page - 1) * $per_page)
                ->limit($per_page)
                ->get()->toArray();
            json([
                'total' => $total,
                'rows'  => $data
            ]);
        } else {
            $this->_view->display(strtolower($this->controller) . '/relation.html');
        }
    }

    #[推荐人列表]
    public function listAction()
    {
        if ($this->isPost()) {
            $type     = $this->get('keywordsType');
            $keywords = $this->get('keywords');
            if ($keywords) {
                array_push($this->search, [$type, '=', $keywords]);
            }
            $startOn = $this->get('start_on');
            if (!empty($startOn)) {
                array_push($this->condition, ['created_at', '>=', $startOn]);
            }
            $endOn = $this->get('end_on');
            if (!empty($endOn)) {
                array_push($this->condition, ['created_at', '<=', $endOn]);
            }
            parent::indexAction();
        } else {
            $this->_view->assign('id', $this->get('id'));
            $this->_view->assign('curr', $this->get('curr'));
            $this->_view->display(strtolower($this->controller) . '/list.html');
        }
    }

    #[变更推荐人]
    public function changeParentAction()
    {
        $inputs = $this->postData;
        $roles  = [
            'id'               => ['role' => 'required|exists:member.id', 'msg' => '用户'],
            'parent_member_id' => ['role' => 'required|exists:member.id', 'msg' => '推荐人'],
        ];
        Validate::check($inputs, $roles);

        if ($inputs['id'] == $inputs['parent_member_id']) {
            ret(30001, '不可绑定自己');
        }

        if (memberchildrenModel::where('member_id', $inputs['id'])->where('children_id', $inputs['parent_member_id'])->exists()) {
            ret(30001, '不能将自己的下线设置为推荐人');
        }

        if (memberchildrenModel::where('member_id', $inputs['id'])->count() > 3000) {
            ret(30002, '会员下线团队过于庞大, 请联系管理员执行变更');
        }

        $member = memberModel::find($inputs['id']);
        if ($member->parent_member_id == $inputs['parent_member_id']) {
            ret(30003, '新旧推荐人相同');
        }

        memberService::changeParent($inputs['id'], $inputs['parent_member_id'], 'admin', $this->auth->user_id, $remark='后台管理员操作变更推荐人');
        $result = [
                'ret' => 0,
                'msg' => '操作成功',
            ];
        json($result);
    }

    #[清空推荐人]
    public function cleanParentAction()
    {
        $inputs = $this->postData;
        $roles  = [
            'id'               => ['role' => 'required|exists:member.id', 'msg' => '用户'],
        ];
        Validate::check($inputs, $roles);

        memberService::cleanParent($inputs['id'], 'admin', $this->auth->user_id, $remark='后台管理员操作清空推荐人');
        $result = [
                'ret' => 0,
                'msg' => '操作成功',
            ];
        json($result);
    }

    #[会员导出]
    public function exportAction()
    {
        $type     = $this->get('keywordsType');
        $keywords = $this->get('keywords');
        $startOn  = $this->get('start_on');
        $endOn    = $this->get('end_on');

        $dirpath = APP_PATH . '/public/excel/';
        if ($dirpath !== '.' && !file_exists($dirpath)) {
            mkdir($dirpath, 0777, true);
        }
        $filename = 'member' . date('Ymd') . uniqid() . '.xlsx';
        $filepath = $dirpath . $filename;
        $res      = exec("php " . APP_PATH . "/public/cli.php export/member \"type={$type}&keywords={$keywords}&startOn={$startOn}&endOn={$endOn}&path={$filepath}\"");
        if ($res === 'Done' && file_exists($filepath)) {
            if( $webpath = syncFile($filepath) ){
                ret(0, '会员导出excel成功', $webpath);
            }
        }
        ret(30003, '会员导出失败');
    }


    #[财务中心用户充值会员列表]
    public function rechargeuserlistAction($returnData = FALSE)
    {
        if ($this->isPost()) {
            $this->model = (new memberModel);
            $type     = $this->get('keywordsType');
            $keywords = $this->get('keywords');
            if ($keywords) {
                array_push($this->search, [$type, '=', $keywords]);
            }
            $startOn = $this->get('start_on');
            if (!empty($startOn)) {
                array_push($this->condition, ['created_at', '>=', $startOn]);
            }
            $endOn = $this->get('end_on');
            if (!empty($endOn)) {
                array_push($this->condition, ['created_at', '<=', $endOn]);
            }
            $status = $this->get('status');
            if (!empty($status)) {
                if($status=='deleted'){
                    $this->model = $this->model->whereNotNull('deleted_at');
                }else{
                    $this->model = $this->model->whereNull('deleted_at');
                    array_push($this->condition, ['status', '=', $status]);
                }
            }
            parent::indexAction(false);
        } else {
            $this->_view->display( strtolower($this->controller) . '/rechargeuserlist.html');
        }
    }
}
